package com.xyz.livelib.camera;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.WindowManager;
import com.xyz.livelib.egl.EglSurfaceView;
import com.xyz.livelib.util.ShaderUtil;


public class CameraEglSurfaceView extends EglSurfaceView implements CameraFboRender.OnSurfaceListener {

    private CameraHelper cameraHelper;
    private CameraFboRender render;
    private int cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
    private int textureId;

    public CameraEglSurfaceView(Context context, int cameraId) {
        this(context, null, cameraId);
    }

    public CameraEglSurfaceView(Context context, AttributeSet attrs, int cameraId) {
        this(context, attrs, 0, cameraId);
    }

    public CameraEglSurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int cameraId) {
        super(context, attrs, defStyleAttr);
        this.cameraId = cameraId;
        init();
    }

    public void init() {
        setRenderMode(RENDERMODE_CONTINUOUSLY);
        cameraHelper = new CameraHelper(getContext());
        render = new CameraFboRender(getContext(), cameraId);
        render.setOnSurfaceListener(this);
        setRender(render);
        previewAngle(getContext());
        setOnClickListener(v -> {
            if (cameraHelper != null) {
                cameraHelper.autoFocus();
            }
        });
        post(() -> {
            if (cameraHelper != null) {
                cameraHelper.autoFocus();
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        render.setScreenW(width);
        render.setScreenH(height);
        cameraHelper.setScreenW(width);
        cameraHelper.setScreenH(height);
    }

    public int getCameraPrivewWidth() {
        return cameraHelper.getPreviewWidth();
    }

    public int getCameraPrivewHeight() {
        return cameraHelper.getPreviewHeight();
    }

    @Override
    public void onSurfaceCreate(SurfaceTexture surfaceTexture, int textureId) {
        cameraHelper.startCamera(surfaceTexture, cameraId);
        this.textureId = textureId;
    }

    public void onDestroy() {
        if (cameraHelper != null) {
            cameraHelper.stopPrive();
            cameraHelper = null;
        }
        if (render != null) {
            render.resetMatirx();
            render = null;
        }
        destroy();
    }

    public void switchCamera() {
        if (isBackCamera()) {
            cameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
        } else {
            cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
        }
//        render.refreshData(cameraId);
//        resetCreate();
        cameraHelper.changeCameraId(cameraId);
//        previewAngle(getContext());
    }

    public boolean isBackCamera() {
        return cameraId == Camera.CameraInfo.CAMERA_FACING_BACK;
    }

    public void previewAngle(Context context) {
        int angle = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
        render.resetMatirx();
        switch (angle) {
            case Surface.ROTATION_0:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    render.setAngle(90, 0, 0, 1);
                    render.setAngle(180, 1, 0, 0);
                } else {
                    render.setAngle(90f, 0f, 0f, 1f);
                }

                break;
            case Surface.ROTATION_90:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    render.setAngle(180, 0, 0, 1);
                    render.setAngle(180, 0, 1, 0);
                } else {
                    render.setAngle(90f, 0f, 0f, 1f);
                }
                break;
            case Surface.ROTATION_180:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    render.setAngle(90f, 0.0f, 0f, 1f);
                    render.setAngle(180f, 0.0f, 1f, 0f);
                } else {
                    render.setAngle(-90, 0f, 0f, 1f);
                }
                break;
            case Surface.ROTATION_270:
                if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    render.setAngle(180f, 0.0f, 1f, 0f);
                } else {
                    render.setAngle(0f, 0f, 0f, 1f);
                }
                break;
        }
    }

    public int getTextureId() {
        return textureId;
    }

    public int getCameraId() {
        return cameraId;
    }
}
